home *** CD-ROM | disk | FTP | other *** search
- /*
- * misc.c
- * Facility: m4 macro processor
- * by: oz
- */
-
- #include "mdef.h"
- #include "extr.h"
-
- #include <signal.h>
- #include <string.h>
- #include <stdlib.h>
- #include <stdarg.h>
-
- static void killdiv (void);
-
- /*
- * indx - find the index of second str in the
- * first str.
- */
- int indx (char *s1, char *s2)
- {
- register char *t;
- register char *p;
- register char *m;
-
- for (p = s1; *p; p++) {
- for (t = p, m = s2; *m && *m == *t; m++, t++)
- ;
- if (!*m)
- return(p - s1);
- }
- return (-1);
- }
-
- /*
- * putback - push character back onto input
- *
- */
- void putback (char c)
- {
- if (bp < endpbb)
- *bp++ = c;
- else
- error("M4: Too many characters pushed back");
- }
-
- /*
- * pbstr - push string back onto input
- * putback is replicated to improve
- * performance.
- *
- */
- void pbstr (char *s)
- {
- register char *es;
- register char *zp;
-
- es = s;
- zp = bp;
-
- while (*es)
- es++;
- es--;
- while (es >= s)
- if (zp < endpbb)
- *zp++ = *es--;
- if ((bp = zp) == endpbb)
- error("M4: Too many characters pushed back");
- }
-
- /*
- * pbnum - convert number to string, push back on input.
- *
- */
- void pbnum (int n)
- {
- register int num;
-
- num = (n < 0) ? -n : n;
- do {
- putback(num % 10 + '0');
- }
- while ((num /= 10) > 0);
-
- if (n < 0) putback('-');
- }
-
- /*
- * putchr - output a single character (or put it on the string space)
- *
- */
- void putchr (char c)
- {
- if (sp < 0)
- {
- if (active != NULL)
- putc(c, active);
- }
- else if (ep < endest)
- *ep++ = c;
- else
- error("M4: String space overflow");
- }
-
- /*
- * putstr - output a string (or put it on the string space)
- *
- */
- void putstr (char *s)
- {
- if (sp < 0)
- {
- if (active != NULL)
- fputs(s, active);
- }
- else if (endest - ep < strlen(s))
- error("M4: String space overflow");
- else
- {
- while (*s)
- *ep++ = *s++;
- }
- }
-
- /*
- * getdiv - read in a diversion file, and trash it.
- * Caller must check that the diversion is in use.
- */
- void getdiv (int ind)
- {
- register int c;
- register FILE *dfil;
-
- if (outfile[ind].fp != NULL)
- error("M4: Undivert: diversion %d still active", ind);
-
- if ((dfil = fopen(outfile[ind].name, "r")) == NULL)
- error("M4: Cannot undivert diversion %d", ind);
-
- if (active != NULL)
- {
- while((c = getc(dfil)) != EOF)
- putc(c, active);
- }
-
- (void) fclose(dfil);
-
- if (remove(outfile[ind].name))
- error("M4: Cannot delete %s", outfile[ind].name);
-
- outfile[ind].ptr = 0L;
- }
-
- /*
- * Very fatal error. Close all files
- * and die hard.
- */
- void error (char *fmt, ...)
- {
- va_list ap;
- killdiv ();
- va_start (ap, fmt);
- vfprintf (stderr, fmt, ap);
- va_end (ap);
- putc ('\n', stderr);
- exit (1);
- }
-
- /*
- * Interrupt handling
- */
- void onintr (int sig)
- {
- if ( sig == SIGINT )
- error ("\nEscape pressed.");
- else
- error ("\nUnexpected signal.");
- }
-
- /*
- * save a string somewhere..
- *
- */
- char *strsave (char *s)
- {
- register int n;
- char *p;
-
- if ((p = malloc (n = strlen(s)+1)) != NULL)
- (void) memcpy(p, s, n);
- return (p);
- }
-
- #define USAGE "Usage: M4 [-D name[=val]] [-U name] [ -o ofile ] file ...\n"
-
- void usage (void)
- {
- fprintf(stderr, USAGE);
- exit(1);
- }
-
- /*
- * killdiv - get rid of the diversion files
- *
- */
- static void killdiv (void)
- {
- register int n;
-
- for (n = 0; n < MAXOUT; n++)
- {
- if (outfile[n].ptr)
- {
- if (outfile[n].fp != NULL)
- (void) fclose (outfile[n].fp);
-
- (void) remove (outfile[n].name);
- outfile[n].ptr = 0L;
- }
- }
- }
-
- #ifdef GETOPT
- /*
- * H. Spencer getopt - get option letter from argv
- *
- *
- #include <stdio.h>
- *
- */
-
- char *optarg; /* Global argument pointer. */
- int optind = 0; /* Global argv index. */
-
- static char *scan = NULL; /* Private scan pointer. */
-
- extern char *index();
-
- int getopt (int argc, char *argv[], char *optstring)
- {
- register char c;
- register char *place;
-
- optarg = NULL;
-
- if (scan == NULL || *scan == '\0') {
- if (optind == 0)
- optind++;
-
- if (optind >= argc || argv[optind][0] != '-' || argv[optind][1] == '\0')
- return(EOF);
- if (strcmp(argv[optind], "--")==0) {
- optind++;
- return(EOF);
- }
-
- scan = argv[optind]+1;
- optind++;
- }
-
- c = *scan++;
- place = index(optstring, c);
-
- if (place == NULL || c == ':') {
- fprintf(stderr, "%s: unknown option -%c\n", argv[0], c);
- return('?');
- }
-
- place++;
- if (*place == ':') {
- if (*scan != '\0') {
- optarg = scan;
- scan = NULL;
- } else {
- optarg = argv[optind];
- optind++;
- }
- }
-
- return(c);
- }
-
- #endif
-
- #ifdef DUFFCP
- /*
- * This code uses Duff's Device (tm Tom Duff)
- * to unroll the copying loop:
- * while (count-- > 0)
- * *to++ = *from++;
- */
-
- #define COPYBYTE *to++ = *from++
-
- void memcpy (char *to, char *from, int count)
- {
- if (count > 0) {
- register int loops = (count+8-1) >> 3; /* div 8 round up */
-
- switch (count&(8-1)) { /* mod 8 */
- case 0: do {
- COPYBYTE;
- case 7: COPYBYTE;
- case 6: COPYBYTE;
- case 5: COPYBYTE;
- case 4: COPYBYTE;
- case 3: COPYBYTE;
- case 2: COPYBYTE;
- case 1: COPYBYTE;
- } while (--loops > 0);
- }
-
- }
- }
-
- #endif
-